package com.awccis.admin.service.impl;

import com.awccis.admin.dao.AdminDao;
import com.awccis.admin.model.AdminBean;
import com.awccis.admin.model.DriverLocationBean;
import com.awccis.admin.model.commission.CommissionBean;
import com.awccis.admin.model.commission.DriverCommissionBean;
import com.awccis.admin.model.order.OrdersCountBean;
import com.awccis.admin.model.pay.PaySimpleInfoBean;
import com.awccis.admin.model.price.PriceBean;
import com.awccis.admin.service.AdminService;
import com.awccis.common.utils.JsonUtil;
import com.awccis.customer.model.CustomerInfo;
import com.awccis.driver.model.DriverDetailInfo;
import com.awccis.driver.model.DriverInfo;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.*;
import java.util.*;

/**
 * @Author: 纯牛奶丶
 * @Date: 2018-04-14 17:24
 * @Since: 1.0
 * @Description:
 **/
@Service("adminServicceImpl")
public class AdminServiceImpl implements AdminService {

    @Resource
    AdminDao adminDao;

    /**
     * admin登录
     *
     * @param adminBean 用户名
     * @return adminBean
     */
    @Override
    public AdminBean adminLogin(AdminBean adminBean) {
        return adminDao.selectAdminInfo(adminBean);
    }

    /**
     * admin重置密码
     *
     * @param map 用户编号 旧密码 新密码
     * @return boolean
     */
    @Override
    public boolean changePwd(HashMap map) {
        return (adminDao.changePwd(map) == 1);
    }

    /**
     * 获取所有的管理员
     *
     * @param level
     * @return
     */
    @Override
    public List<AdminBean> getAllAdminInfo(int level) {
        return adminDao.selectAdminList(level);
    }

    /**
     * 通过id删除admin
     *
     * @param id 管理员id
     * @return 影响的行数
     */
    @Override
    public boolean deleteAdminById(int id) {
        return adminDao.deleteAdminById(id) == 1;
    }

    /**
     * 添加管理员
     *
     * @param hashMap adminName adminPasswd adminPowerLevel
     * @return true or false
     */
    @Override
    public boolean addAdmin(HashMap hashMap) {
        return adminDao.insertAdmin(hashMap) == 1;
    }

    /**
     * 获取所有用户
     *
     * @return CustomerInfo's collection
     */
    @Override
    public LinkedList<CustomerInfo> getAllCustomers() {
        return adminDao.selectCustomers();
    }

    /**
     * 查询所有司机
     *
     * @return
     */
    @Override
    public LinkedList<DriverInfo> getAllDrivers() {
        return adminDao.selectDrivers();
    }

    /**
     * 查询司机信息
     *
     * @param type  查询类型
     * @param value 查询条件
     * @return 列表
     */
    @Override
    public LinkedList<DriverInfo> selectDriverFuzzy(String type, Object value) {
        LinkedList<DriverInfo> list;
        switch (type){
            case "nickName":
                try {
                    list = adminDao.selectDriversByNickName(Integer.parseInt(value.toString()));
                } catch (NumberFormatException e) {
                    System.out.println(e.toString());
                    list = new LinkedList<>();
                }
                break;
            default:
                list = new LinkedList<>();
                break;
        }
        return list;
    }

    /**
     * 查询司机的个人详细信息
     *
     * @param driverId
     * @return
     */
    @Override
    public DriverDetailInfo getDriverDetailInfo(int driverId) {
        return adminDao.selectDriverDetailInfoById(driverId);
    }

    /**
     * 注销账户
     *
     * @param driverId driverId
     * @return 执行结果
     */
    @Override
    public Integer logoffDriverAccount(int driverId) {
        return adminDao.updateDriverPhoneNull(driverId);
    }

    /**
     * 获取人民币与加元汇率
     *
     * @return
     */
    @Override
    public Double getExchangeRate() {
        return adminDao.selectExchangeRate();
    }

    /**
     * 获取所有在线的司机的位置和简单信息
     *
     * @return list
     */
    @Override
    public List<DriverLocationBean> getDriverLocationWithOnline() {
        return adminDao.selectDriverLocationInfo();
    }

    /**
     * 更改价格
     *
     * @param priceBean priceBean
     * @return 更改结果
     */
    @Override
    public Boolean updatePrice(PriceBean priceBean) {
        boolean result = false;

        int priceId = priceBean.getPriceId();

        PriceBean pbBefore;
        PriceBean pbAfter;

        List<PriceBean> list = adminDao.selectPriceDetailInfo();
        for (int i = priceId; i <= list.size(); i++) {
            /**
             * 判断修改的规则是否为第一条规则，若是则获取的前一条规则数值为第一条未修改前的数值，
             * 否则获取前一条规则的数值
             */
            if (1 < i) {
                pbBefore = list.get(i - 2);
            } else {
                pbBefore = list.get(i - 1);
            }
            /**
             * 获取本条规则未修改前的数值（区间结束距离，区间费率，区间补贴）
             */
            pbAfter = list.get(i - 1);

            PriceBean pBean = new PriceBean();

            //区间起步距离
            int travelStart;
            //区间起步价格
            double startCost;
            //区间结束距离
            int travelEnd;
            //区间结束价格
            double endCost;
            //区间费率
            double ratio;
            //区间补贴
            int pension;

            /**
             * 在更改的为第一条规则时候，区间起步距离，起步价格，结束价格为指定的数值，
             * 非第一条规则，起步距离、起步价格、结束价格为前一条规则的区间结束距离、结束价格
             */
            if (i == 1) {
                travelStart = 0;
                startCost = 0;
                travelEnd = priceBean.getPriceTravelEnd();
                endCost = priceBean.getPriceEndCost();
            } else {
                travelStart = pbBefore.getPriceTravelEnd();
                startCost = pbBefore.getPriceEndCost();
                endCost = pbBefore.getPriceEndCost();
            }

            pBean.setPriceId(i);
            pBean.setPriceTravelStart(travelStart);
            pBean.setPriceStartCost(startCost);

            /**
             * 判断是否为指定要修改的规则，是则区间的结束距离、区间费率、补贴为指定的数值，
             * 否则区间结束距离、区间费率、区间补贴为此条规则未修改前的数值
             */
            if (priceId == i) {
                travelEnd = priceBean.getPriceTravelEnd();
                ratio = priceBean.getPriceRatio();
                pension = priceBean.getPricePension();
            } else {
                travelEnd = pbAfter.getPriceTravelEnd();
                ratio = pbAfter.getPriceRatio();
                pension = pbAfter.getPricePension();
            }

            /**
             * 在list中记录此条规则要修改的区间结束距离的数值
             */
            pBean.setPriceTravelEnd(travelEnd);
            list.get(i - 1).setPriceTravelEnd(travelEnd);
            /**
             * 在list中记录此条规则要修改的区间结束价格的数值
             */
            double nowCost = endCost + (travelEnd - pbBefore.getPriceTravelEnd()) * ratio * 2;
            pBean.setPriceEndCost(nowCost);
            list.get(i - 1).setPriceEndCost(nowCost);
            pBean.setPriceRatio(ratio);
            pBean.setPricePension(pension);

            result = adminDao.updatePriceById(pBean) == 1;
        }

        return result;
    }

    /**
     * 获取所有价格体系规则
     *
     * @return list
     */
    @Override
    public List<PriceBean> getAllPriceRule() {
        return adminDao.selectPriceDetailInfo();
    }

    /**
     * 更改价格体系
     *
     * @param list list
     * @return 更改结果
     */
    @Override
    public Boolean updatePriceRule(List<PriceBean> list) {
        boolean result;
        //先清空表内数据
        if (list.size() > 0) {
            adminDao.deleteFromPrice();
        }
        //重新插入数据
        result = adminDao.insertPriceDetailInfo(list) == list.size();
        return result;
    }

    /**
     * 获取所有抽成体系规则
     *
     * @return list
     */
    @Override
    public List<CommissionBean> getAllCommissionRule() {
        return adminDao.selectCommissionRule();
    }

    /**
     * 更改抽成体系
     *
     * @param list list
     * @return 更改结果
     */
    @Override
    public Boolean updateCommissionRule(List<CommissionBean> list) {
        boolean result;

        if (list.size() > 0) {
            adminDao.deleteAllCommissionRule();
        }
        result = adminDao.insertCommissionRule(list) == list.size();

        return result;
    }

    /**
     * 获取所有需要支付平台费用的司机
     * <p>
     * 在定时任务中，直接调用此接口，计算价格，并向数据库表中记录本周需要缴纳费用的信息
     *
     * @return list
     */
    @Override
    public List<PaySimpleInfoBean> getAllDriverNeedPay(String payWeek) {
        List<PaySimpleInfoBean> list = adminDao.selectAllDriverNeedPay();
        System.out.println("需要缴费的driver" + list);
        List<PaySimpleInfoBean> listResult = new ArrayList<>();

        //adminDao.deletePayRecord();

        //判断是否已经存在本周需要支付费用的司机,若已经存在，则直接查询所有需要支付的司机，不存在则开始计算
        int resultPayWeeks = adminDao.selectPayRecordCounts(payWeek);
        if (resultPayWeeks == list.size()) {
            listResult = adminDao.selectDriverPayDirectly(payWeek);
            return listResult;
        } else {
            for (PaySimpleInfoBean p : list) {
                p.setPayWeek(payWeek);
            }
            //初始化本周所有需要缴费的司机
            boolean result = adminDao.insertDriverNeedPay(list) == list.size();
            System.out.println("初始化缴费司机：" + result);
            if (result) {
                //初始化本周所有司机的费率
                boolean initCommission = initDriverCommission(payWeek);
                System.out.println("初始化费率：" + initCommission);
                if(initCommission){
                    //计算每个司机的缴纳费用和其他信息
                    for (PaySimpleInfoBean p : list) {
                        p.setNeedPay(adminDao.callDriverNeedPay(p.getDriverId()));
                        p.setDriverName(p.getDriverName());
                        p.setDriverPhone(p.getDriverPhone());
                        listResult.add(p);
                    }
                    boolean updateResult = adminDao.updateDriverNeedPay(listResult) == listResult.size();
                }
            } else {
                listResult.add(new PaySimpleInfoBean());
            }
        }

        return listResult;
    }

    /**
     * 直接获取所有需要支付平台费用的司机
     *
     * @return list
     */
    @Override
    public List<PaySimpleInfoBean> getAllDriverNeedPayDirectly(String payWeek) {
        Double exchangeRate = getExchangeRate();
        List<PaySimpleInfoBean> list = adminDao.selectDriverPayDirectly(payWeek);
        for (PaySimpleInfoBean p : list){
            p.setNeedPay(p.getNeedPay() * exchangeRate);
        }
        return list;
    }

    /**
     * 记录访问信息
     *
     * @param map 1
     */
    @Override
    public void recordVisitInfo(Map map) {
        try {
            String path = JsonUtil.getJsonConfigValue("visitInfoLogPath");
            if (!new File(path).exists()) {
                new File(path).mkdirs();
            }
            File file = new File(path, "adminVisitInfo.log");

            BufferedWriter br = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file, true)));
            br.write(String.valueOf(map.get("date")) + "," + map.get("os") + "," + map.get("model") + "," + map.get("ip") + "\n");
            br.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取所有司机的抽成比例
     *
     * @return 返回抽成比例列表
     */
    @Override
    public List<DriverCommissionBean> getAllDriverCommission() {
        return adminDao.selectDriverCommission();
    }

    /**
     * 更改driverCommission
     *
     * @param driverCommissionBean driverCommission
     * @return 执行结果
     */
    @Override
    public Boolean setDriverCommission(DriverCommissionBean driverCommissionBean) {
        return adminDao.updateDriverCommission(driverCommissionBean) == 1;
    }

    /**
     * 初始化抽成比例
     *
     * @return 执行结果
     */
    @Override
    public Boolean initDriverCommission(String punishWeek) {
        List<OrdersCountBean> countList = adminDao.selectAllDriverOrdersCount();
        List<DriverCommissionBean> commissionBeanList = new ArrayList<>();
        DriverCommissionBean commissionBean;

        for (OrdersCountBean countBean : countList) {
            commissionBean = new DriverCommissionBean();
            commissionBean.setDriverId(countBean.getDriverId());
            Double d = adminDao.calculateDriverCommission(countBean.getDriverId(), countBean.getSumOrder());
            commissionBean.setPunishCommission(d == null ? adminDao.selectBasicsCommission(): d);
            Double d2 = adminDao.selectDriverLastCommission(countBean.getDriverId());
            commissionBean.setPunishMark(d2 == null ? 0 : d2);
            commissionBean.setPunishSum(commissionBean.getPunishCommission() + commissionBean.getPunishMark());
            commissionBean.setPunishWeek(punishWeek);
            commissionBeanList.add(commissionBean);
        }

        boolean result = adminDao.insertDriverCommission(commissionBeanList) == countList.size();

        return result;
    }
}